package repository

type {{upperCamelCase .TableName}} struct{
    {{range $column := .Columns -}}
    {{upperCamelCase .ColumnName }} {{.GoLangType}} {{.Tag}}
    {{end -}}
}

func (entity *{{upperCamelCase .TableName}}) Copy(target *{{upperCamelCase .TableName}},columns []string) ([]string,[]utility.BeanUpdateLogItem){
    updateColumns:=make([]string,0,len({{lowerCamelCase .TableName}}Columns))
    updateLogItems:=make([]utility.BeanUpdateLogItem,0,len({{lowerCamelCase .TableName}}Columns))

    columnMap := make(map[string]string)

    for _,column := range columns {
        columnMap[column]=column
    }

    {{range $column := .Columns -}}
    if _,ok:=columnMap["{{upperCamelCase .ColumnName}}"];!ok && entity.{{upperCamelCase .ColumnName}} != target.{{upperCamelCase .ColumnName}}{
         updateColumns = append(updateColumns,"{{.ColumnName}}")
         updateLogItems = append(updateLogItems,utility.BeanUpdateLogItem{PropertyName:"{{upperCamelCase .ColumnName}}",OldProperyValue:entity.{{upperCamelCase .ColumnName}},NewPropertyValue:target.{{upperCamelCase .ColumnName}}})

         target.{{upperCamelCase .ColumnName}} = entity.{{upperCamelCase .ColumnName}}
    }
    {{end -}}
}

{{if not .Readonly}}
    var(
        {{lowerCamelCase .TableName}}Columns=[]string{
            {{range $column := .Columns -}}
            "{{.ColumnName}}",
            {{end -}}
        }
        {{lowerCamelCase .TableName}}ColumnMap=map[string]string{
            {{range $column := .Columns -}}
            "{{.ColumnName }}":"{{.ColumnName}}",
            {{end -}}
        }
    )
{{end}}
type {{upperCamelCase .TableName}}Repository interface {
    {{- if not .Readonly}}
    Create(entity {{upperCamelCase .TableName}}) ({{upperCamelCase .TableName}}, error)
    {{- end -}}
    {{- if not .Readonly}}
    CreateBySession(session *xorm.Session, entity {{upperCamelCase .TableName}}) ({{upperCamelCase .TableName}}, error)
    {{- end -}}
    {{- if not .Readonly}}
    DeleteById(id int64) (int64, error)
    {{- end -}}
    {{- if not .Readonly}}
    DeleteBySessionAndId(session *xorm.Session, id int64) (int64, error)
    {{- end -}}
    {{- if not .Readonly}}
    Update(entity {{upperCamelCase .TableName}}, columns []string) ({{upperCamelCase .TableName}}, error)
    {{- end -}}
    {{- if not .Readonly}}
    UpdateBySession(session *xorm.Session, entity {{upperCamelCase .TableName}}, columns []string) ({{upperCamelCase .TableName}}, error)
    {{- end}}
    FindById(id int64) ({{upperCamelCase .TableName}}, error)
    FindBySessionAndId(session *xorm.Session, id int64) ({{upperCamelCase .TableName}}, error)
}

type {{lowerCamelCase .TableName}}Repository  struct {
    engine *xorm.Engine
}

func New{{upperCamelCase .TableName}}Repository(engine *xorm.Engine) {{upperCamelCase .TableName}}Repository {
    return &{{lowerCamelCase .TableName}}Repository{
        engine: engine,
    }
}

{{if not .Readonly}}
func (r *{{lowerCamelCase .TableName}}Repository) Create(entity {{upperCamelCase .TableName}}) ({{upperCamelCase .TableName}}, error) {
    _, err := r.engine.Insert(&entity)

    return entity, err
}
{{end -}}

{{if not .Readonly}}
func (r *{{lowerCamelCase .TableName}}Repository) CreateBySession(session *xorm.Session, entity {{upperCamelCase .TableName}}) ({{upperCamelCase .TableName}}, error) {
    _, err := session.Insert(&entity)

    return entity, err
}
{{end -}}

{{if not .Readonly}}
func (r *{{lowerCamelCase .TableName}}Repository) DeleteById(id int64) (int64, error) {
    {{- if .HasDelStatus}}
    return r.engine.ID(id).Cols("del_status", "update_time").Update(&{{upperCamelCase .TableName}}{DelStatus: 1, UpdateTime: core.LocalDateTime(time.Now())})
    {{- else}}
    return r.engine.ID(id).Delete(&{{upperCamelCase .TableName}}{})
    {{- end}}
}
{{end -}}

{{if not .Readonly}}
func (r *{{lowerCamelCase .TableName}}Repository) DeleteBySessionAndId(session *xorm.Session, id int64) (int64, error) {
    {{- if .HasDelStatus}}
    return session.ID(id).Cols("del_status", "update_time").Update(&{{upperCamelCase .TableName}}{DelStatus: 1, UpdateTime: core.LocalDateTime(time.Now())})
    {{- else}}
    return session.ID(id).Delete(&{{upperCamelCase .TableName}}{})
    {{- end}}
}
{{end -}}

{{if not .Readonly}}
func (r *{{lowerCamelCase .TableName}}Repository) Update(entity {{upperCamelCase .TableName}},columns []string) ({{upperCamelCase .TableName}}, error) {
    _, err := r.engine.ID(entity.Id).Cols(columns...).Update(&entity)

    return entity, err
}
{{end -}}

{{if not .Readonly}}
func (r *{{lowerCamelCase .TableName}}Repository) UpdateBySession(session *xorm.Session, entity {{upperCamelCase .TableName}},columns []string) ({{upperCamelCase .TableName}}, error) {
    _, err := session.ID(entity.Id).Cols(columns...).Update(&entity)

    return entity, err
}
{{end}}

func (r *{{lowerCamelCase .TableName}}Repository) FindById(id int64) ({{upperCamelCase .TableName}}, error) {
    entity := new({{upperCamelCase .TableName}})

    _, err := r.engine.ID(id){{if .HasDelStatus}}.Where("del_status=0"){{end}}.Get(entity)

    return *entity, err
}

func (r *{{lowerCamelCase .TableName}}Repository) FindBySessionAndId(session *xorm.Session, id int64) ({{upperCamelCase .TableName}}, error) {
    entity := new({{upperCamelCase .TableName}})

    _, err := session.ID(id){{if .HasDelStatus}}.Where("del_status=0"){{end}}.Get(entity)

    return *entity, err
}